home *** CD-ROM | disk | FTP | other *** search
/ Enigma Amiga Life 109 / EnigmaAmiga109CD.iso / dalla rivista / amiga.free / sorgenti vari / wolf3dmacsource.sit / Wolf3DMacSource / PickAMonitor.c < prev    next >
C/C++ Source or Header  |  2000-01-21  |  9KB  |  335 lines

  1. #include "WolfDef.h"
  2. #include <Palettes.h>
  3. #include <gestalt.h>
  4. #include "PickAMonitor.h"
  5.  
  6. #define    PAMStrings        2001
  7. #define    NoColorString        1
  8. #define    NoDepthString        2
  9. #define    NoSizeString        3
  10. #define    NoProblemString    4
  11.  
  12. void CheckMonitor(DialogPtr theWindow, int bitDepth, Boolean colorRequired, short minWidth, short minHeight);
  13. void OutlineOK(DialogPtr theDialog, Boolean enabled);
  14.  
  15. /**********************************
  16.  
  17.     Take a window pointer and center it onto the
  18.     current video device
  19.         
  20. **********************************/
  21.  
  22. void CenterWindowOnMonitor(WindowPtr theWindow, GDHandle theMonitor)
  23. {
  24.     short    newH, newV;
  25.     Rect    mRect;
  26.  
  27.     mRect = (**theMonitor).gdRect;        /* Get the rect of the monitor */
  28.  
  29.     /*    Find the difference between the two monitors' sizes */
  30.     newH = (mRect.right - mRect.left) - (theWindow->portRect.right - theWindow->portRect.left);
  31.     newV = (mRect.bottom - mRect.top) - (theWindow->portRect.bottom - theWindow->portRect.top);
  32.  
  33.     /*    Half the difference so that it's centered top-to-bottom and left-to-right */
  34.     /*    Add that offset to the upper-left of the monitor */
  35.  
  36.     MoveWindow(theWindow,(newH>>1)+mRect.left,(newV>>1)+mRect.top,TRUE); /* Move and bring to front */
  37. }
  38.  
  39. /**********************************
  40.  
  41.     Returns true if the device supports color
  42.         
  43. **********************************/
  44.  
  45. Boolean SupportsColor(GDHandle theMonitor)
  46. {
  47.     return TestDeviceAttribute(theMonitor,gdDevType);        /* Is it color? */
  48. }
  49.  
  50. /**********************************
  51.  
  52.     Returns true if the device supports a specific color depth
  53.         
  54. **********************************/
  55.  
  56. short SupportsDepth(GDHandle theMonitor, int theDepth, Boolean needsColor)
  57. {
  58.     return HasDepth(theMonitor,theDepth,1<<gdDevType,needsColor);
  59. }
  60.  
  61. /**********************************
  62.  
  63.     Returns true if the device supports a specific video size
  64.         
  65. **********************************/
  66.  
  67. Boolean SupportsSize(GDHandle theMonitor, short theWidth, short theHeight)
  68. {
  69.     Rect theRect;
  70.  
  71.     /* Grab the dimensions of the monitor */
  72.     theRect = (**theMonitor).gdRect;
  73.  
  74.     /* Offset it to (0, 0) references */
  75.     OffsetRect(&theRect, -theRect.left, -theRect.top);
  76.     
  77.     /* Check the dimensions to see if they are large enough */
  78.     if ((theRect.right < theWidth) || (theRect.bottom < theHeight)) {
  79.         return FALSE;        /* No good! */
  80.     }
  81.     return TRUE;
  82. }
  83.  
  84. /**********************************
  85.  
  86.     Return the GDevice from a specific quickdraw point
  87.         
  88. **********************************/
  89.  
  90. GDHandle MonitorFromPoint(Point *thePoint)
  91. {
  92.     GDHandle theMonitor;
  93.  
  94.     /*    Loop through the list of monitors to see one encompasses the point */
  95.     theMonitor = GetDeviceList();    /* Get the first monitor */
  96.     do {
  97.         if (PtInRect(*thePoint,&(**theMonitor).gdRect)) {    /* Is this it? */
  98.             break;            /* Exit now */
  99.         }
  100.         theMonitor = GetNextDevice(theMonitor);        /* Get the next device in list */
  101.     } while (theMonitor);        /* All done now? */
  102.  
  103.     /*    Just in case some weird evil happened, return a fail value (THEORETICALLY can't happen) */
  104.     return theMonitor;
  105. }
  106.  
  107.  
  108.  
  109. //¥    ----------------------------------------    PickAMonitor
  110.  
  111. GDHandle PickAMonitor(int theDepth, Boolean colorRequired, short minWidth, short minHeight)
  112. {
  113.     GDHandle    theMonitor;
  114.     GDHandle    tempMonitor;
  115.     Point        thePoint;
  116.     EventRecord    theEvent;
  117.     DialogPtr    theDialog;
  118.     short    itemHit;
  119.     char    theChar;
  120.     Word    validCount;
  121.     GrafPtr    savedPort;
  122.  
  123.     /*    Loop through the monitor list once to make sure there is at least one good monitor */
  124.     theMonitor = GetDeviceList();        /* Get the first monitor */
  125.     tempMonitor = 0;                    /* No monitor found */
  126.     validCount = 0;                        /* None found */
  127.     do {
  128.         if (colorRequired && !SupportsColor(theMonitor)) {    /* Check for color? */
  129.             continue;
  130.         }
  131.  
  132.         if (!SupportsDepth(theMonitor, theDepth, colorRequired)) { /* Check for bit depth */
  133.             continue;
  134.         }
  135.  
  136.         if (!SupportsSize(theMonitor, minWidth, minHeight))    {    /* Check for monitor size */
  137.             continue;
  138.         }
  139.         tempMonitor = theMonitor;        /* Save the valid record */
  140.         ++validCount;                    /* Inc the count */
  141.     } while ((theMonitor = GetNextDevice(theMonitor)) != 0);
  142.  
  143.     /*    If there was only one valid monitor, goodMonitor will be referencing it.  Return it immediately. */
  144.     if (validCount == 1) {
  145.         return (tempMonitor);        /* Exit now */
  146.     }
  147.  
  148.     /* If there are no valid monitors then put up a dialog saying so.  Then return nil. */
  149.  
  150.     if (!validCount) {
  151.         StopAlert(2001, nil);
  152.         return 0;
  153.     }
  154.  
  155.     //¥    Start an event loop going.  Rather than using modalDialog with a gnarly filter, we'll just display the dialog
  156.     //¥    then use a gnarly event loop to accommodate it.  This will go on until the user selects either "This Monitor"
  157.     //¥    (ok) or "Quit" (cancel).
  158.     
  159.     theDialog = GetNewDialog(2000, nil, (WindowPtr) -1L);
  160.     CenterWindowOnMonitor((WindowPtr) theDialog, GetMainDevice());
  161.     InitCursor();
  162.     GetPort(&savedPort);
  163.     SetPort(theDialog);
  164.     
  165.     ShowWindow(theDialog);
  166.     CheckMonitor(theDialog, theDepth, colorRequired, minWidth, minHeight);
  167.  
  168.     do {
  169.         itemHit = 0;
  170.         
  171.         /*    Get next event from the event queue */
  172.         if (WaitNextEvent2(everyEvent&(~highLevelEventMask), &theEvent, 30, nil)) {
  173.             switch (theEvent.what) {
  174.                 case keyDown:
  175.                     theChar = theEvent.message & charCodeMask;
  176.                     if ((theEvent.modifiers & cmdKey) && ((theChar == '.') || (theChar == 'q') || (theChar == 'Q'))) {
  177.                         itemHit = cancel;
  178.                         break;
  179.                     }
  180.                     
  181.                     if (theChar == 0x1B) {
  182.                         itemHit = cancel;
  183.                         break;
  184.                     }
  185.                     
  186.                     if ((theChar == 0x0D) || (theChar == 0x03)) {
  187.                         itemHit = ok;
  188.                         break;
  189.                     }
  190.                     
  191.                     break;
  192.             
  193.                 //¥    Did we mouse-down in the dialogs drag-bar?
  194.                 case mouseDown:
  195.                     if (FindWindow(theEvent.where, (WindowPtr *) &theDialog) == inDrag)
  196.                     {
  197.                         DragWindow((WindowPtr) theDialog, theEvent.where, &qd.screenBits.bounds);
  198.                         GetMouse(&thePoint);
  199.                         LocalToGlobal(&thePoint);
  200.                         tempMonitor = MonitorFromPoint(&thePoint);
  201.                         CenterWindowOnMonitor((WindowPtr) theDialog, tempMonitor);
  202.                         CheckMonitor(theDialog, theDepth, colorRequired, minWidth, minHeight);
  203.                         break;
  204.                     }
  205.  
  206.                 default:
  207.                     //¥    If not, perform regular dialog event processing
  208.                     DialogSelect(&theEvent, &theDialog, &itemHit);
  209.             }
  210.         }
  211.     } while ((itemHit != ok) && (itemHit != cancel));
  212.  
  213.     //¥    Ok, the dialog is still the active grafport so all coordinates are in its local system.  If I define a point
  214.     //¥    as (0, 0) now it will be the upper left corner of the dialog's drawing area.  I then turn this to a global screen
  215.     //¥    coordinate and call GetMonitorFromPoint.
  216.     
  217.     SetPt(&thePoint, 0, 0);
  218.     LocalToGlobal(&thePoint);
  219.     theMonitor = MonitorFromPoint(&thePoint);
  220.  
  221.     //¥    Restore our current graphics environment and return the monitor reference.
  222.     SetPort(savedPort);
  223.     DisposeDialog(theDialog);
  224.  
  225.     if (itemHit == ok) {
  226.         return (theMonitor);
  227.     }
  228.     return (nil);
  229. }
  230.  
  231.  
  232.  
  233.  
  234. //¥    ----------------------------------------    CheckMonitor
  235.  
  236. void CheckMonitor(DialogPtr theDialog, int bitDepth, Boolean colorRequired, short minWidth, short minHeight)
  237. {
  238. GDHandle    theMonitor;
  239. Point        thePoint;
  240. short    theType;
  241. Handle    theHandle;
  242. Rect        theRect;
  243. Str255    message;
  244. Boolean    badMonitor = FALSE;
  245.  
  246. GrafPtr    savedPort;
  247.  
  248.     GetPort(&savedPort);
  249.     SetPort((WindowPtr) theDialog);
  250.     SetPt(&thePoint, 0, 0);
  251.     LocalToGlobal(&thePoint);
  252.     theMonitor = MonitorFromPoint(&thePoint);
  253.  
  254.     GetDialogItem(theDialog, 4, &theType, &theHandle, &theRect);
  255.     
  256.     if (colorRequired && ! SupportsColor(theMonitor)) {
  257.         GetIndString(message, PAMStrings, NoColorString);
  258.         SetDialogItemText(theHandle, message);
  259.         badMonitor = TRUE;
  260.     }
  261.     
  262.     if (!SupportsDepth(theMonitor, bitDepth, colorRequired)) {
  263.         GetIndString(message, PAMStrings, NoDepthString);
  264.         SetDialogItemText(theHandle, message);
  265.         badMonitor = TRUE;
  266.     }
  267.  
  268.     if (! SupportsSize(theMonitor, minWidth, minHeight)) {
  269.         GetIndString(message, PAMStrings, NoDepthString);
  270.         SetDialogItemText(theHandle, message);
  271.         badMonitor = TRUE;
  272.     }
  273.  
  274.     SetPort(savedPort);
  275.     
  276.     if (badMonitor) {
  277.         //¥    Gray-out the "This Monitor" button
  278.         GetDialogItem(theDialog, ok, &theType, &theHandle, &theRect);
  279.         HiliteControl((ControlHandle) theHandle, 255);
  280.         OutlineOK(theDialog, FALSE);
  281.         BeginUpdate((WindowPtr) theDialog);
  282.         UpdateDialog(theDialog, theDialog->visRgn);
  283.         EndUpdate((WindowPtr) theDialog);
  284.         return;
  285.     }
  286.  
  287.     //¥    Activate the "This Monitor" button and put up the no problem text.
  288.     GetIndString(message, PAMStrings, NoProblemString);
  289.     SetDialogItemText(theHandle, message);
  290.     GetDialogItem(theDialog, ok, &theType, &theHandle, &theRect);
  291.     HiliteControl((ControlHandle) theHandle, 0);
  292.     OutlineOK(theDialog, TRUE);
  293.     BeginUpdate((WindowPtr) theDialog);
  294.     UpdateDialog(theDialog, theDialog->visRgn);
  295.     EndUpdate((WindowPtr) theDialog);
  296. }
  297.  
  298. //¥    ----------------------------------------    OutlineOK
  299.  
  300. void OutlineOK(DialogPtr theDialog, Boolean enabled)
  301. {
  302. GrafPtr    savedPort;
  303.  
  304. ColorSpec    saveColor;
  305. PenState    savedState;
  306.  
  307. short    theType;
  308. Handle    theHandle;
  309. Rect        theRect;
  310.  
  311.     GetPenState(&savedState);
  312.     PenMode(patCopy);
  313.     PenSize(2, 2);
  314.  
  315.     SaveFore(&saveColor);
  316.     ForeColor(blackColor);
  317.  
  318.     GetPort(&savedPort);
  319.     SetPort((WindowPtr) theDialog);
  320.  
  321.     GetDialogItem(theDialog, ok, &theType, &theHandle, &theRect);
  322.     InsetRect(&theRect, -4, -4);
  323.     
  324.     if (enabled)
  325.         PenPat(&qd.black);
  326.     else
  327.         PenPat(&qd.gray);
  328.     
  329.     FrameRoundRect(&theRect, 16, 16);
  330.     
  331.     SetPort(savedPort);
  332.     RestoreFore(&saveColor);
  333.     SetPenState(&savedState);
  334. }
  335.